<?php

namespace app\common\component;

use app\common\model\Shop;

/**
 * 主要用来微信授权
 */
trait WxBase
{

    //以wx_config里面的type为标准
    protected $openPlatform = false;

    //授权之后回调地址
    protected $accredit_backurl = 's_accredit_backurl';

    protected $userId = 0;


    /**
     * 网页授权链接
     */
    protected $url_authorize = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect';

    /**
     * 获取授权用户信息
     */
    protected $url_snsapi_userinfo = 'https://api.weixin.qq.com/sns/userinfo';

    /**
     * unionid机制获取用户信息
     */
    protected $url_userinfo = 'https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN';

    /**
     * 通过code换取网页授权access_token
     */
    protected $url_code_to_access = 'https://api.weixin.qq.com/sns/oauth2/access_token';

    /**
     * 开放平台授权链接（开放平台配的地址）
     */
    private $open_authorize_url = 'http://platform.meigm.cn/ucenter/wx_base/author';

    //授权跳转地址(默认)
    public $authorize_url = '/index/index/author';


    protected function getConfig()
    {
        $shop = new Shop();
        $info = $shop->where('status', 1)->order('id', 'desc')->find();
        if (!$info) ajaxError('暂无收款商户');
        return $info;
    }


    protected function getRedirectUrl($backurl)
    {
        return 'http://' . $_SERVER['HTTP_HOST'] . $this->authorize_url . '?backurl=' . base64_encode($backurl);
    }

    protected function getJsParamsUrl()
    {
        $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
        return $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    }


    /**
     * 授权登陆
     * @param int $platformId
     * @param string $params
     * @param string $scope snsapi_base snsapi_userinfo
     * @param string $backurl
     */
    public function oauthLogin($platformId, $params = '', $scope = 'snsapi_base', $backurl = '')
    {
        $config = $this->getConfig($platformId);
        $backurl = empty($backurl) ? 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] : $backurl;
        $redirect_url = $this->getRedirectUrl($backurl);
        $state = base64_encode(json_encode(['params' => $params, 'platform_id' => $platformId]));

        $url = str_replace(['APPID', 'REDIRECT_URI', 'SCOPE', 'STATE'], [$config['appid'], urlencode($redirect_url), $scope, $state], $this->url_authorize);

        session($this->accredit_backurl, $backurl);
        header('Location:' . $url);
        exit;
    }

    /**
     * 获取jsSDK的参数
     * 获取jsSDK的参数
     * @param int $platformId
     * @return array
     */
    public function getJsParams($platformId)
    {
        $jsApiTicket = $this->getJsApiTicket($platformId);

        $url = $this->getJsParamsUrl();

        $timestamp = time();
        $nonceStr = $this->createNonceStr();

        $string = "jsapi_ticket=$jsApiTicket&noncestr=$nonceStr&timestamp=$timestamp&url=$url";
        $config = $this->getConfig();
        $signPackage = [
            'appId' => $config['appid'],
            'nonceStr' => $nonceStr,
            'timestamp' => $timestamp,
            'url' => $url,
            'signature' => sha1($string)
        ];
        return $signPackage;
    }


    /**
     * 通过接口获取微信用户信息
     * @param string $openId
     * @param string $token
     */
    public function getUserInfoByWxApi($openid, $token)
    {
        $url = $this->url_snsapi_userinfo . "?access_token=" . $token . "&openid=" . $openid . "&lang=zh_CN";
        $result = file_get_contents($url);
        $result = json_decode($result, true);
        if (isset($result['errcode'])) {
            exit('拉取用户信息失败' . $result['errmsg']);
        }
        return $result;
    }


    private function createNonceStr($length = 16)
    {
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }

    private function getJsApiTicket($platformId)
    {
        $jsApiTicket = cache($platformId . '_jsapiTicket');
        if (empty($jsApiTicket)) {

            $accessToken = $this->getAccessToken($platformId);

            $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=$accessToken";
            $result = file_get_contents($url);
            $result = json_decode($result, true);
            if (empty($result) || empty($result['ticket'])) {
                exit('获取jsapi_ticket失败');
            }
            cache($platformId . '_jsapiTicket', $result['ticket'], $result['expires_in']);
            $jsApiTicket = $result['ticket'];
        }
        return $jsApiTicket;
    }

    /**
     * 获取accessToken
     * @param int $platformId
     */
    public function getAccessToken($platformId)
    {
        $result = cache($platformId . 'access_token');
        if (empty($result) || NOW_TIME - $result['time'] >= 7200) {
            $config = $this->getConfig();
            $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' . $config['appid'] . '&secret=' . $config['appSecret'];
            $result = file_get_contents($url);
            $result = json_decode($result, true);
            if (empty($result) || empty($result['access_token'])) {
                exit('访问微信接口获取access_token失败' . (empty($result['errmsg']) ? '' : $result['errmsg']));
            }
            $result['time'] = NOW_TIME;
            cache($platformId . 'access_token', $result);
            $accessToken = $result['access_token'];
        } else {
            $accessToken = $result['access_token'];
        }
        return $accessToken;
    }

    /**
     * 通过code换取access_token和openid
     */
    public function getCodeToAccess($platformId, $code)
    {
        $config = $this->getConfig();

        $url = $this->url_code_to_access . '?appid=' . $config['appid'] . '&secret=' . $config['appSecret'] . '&code=' . $code . '&grant_type=authorization_code';

        $result = file_get_contents($url);
        $result = json_decode($result, true);
        if (isset($result['errcode'])) {
            exit($result['errcode'] . ':用户获取失败' . $result['errmsg']);
        }
        return $result;
    }
}

